package mapspinner.persistence.rmi;

import java.net.MalformedURLException;
import java.rmi.Naming;
import java.rmi.Remote;
import java.rmi.RemoteException;
import java.rmi.registry.LocateRegistry;
import java.rmi.server.UnicastRemoteObject;

import mapspinner.TerrainKey;
import mapspinner.persistence.TerrainPersistence;
import mapspinner.persistence.datatypes.TerrainData;
import mapspinner.persistence.datatypes.TerrainSettings;
import mapspinner.persistence.disk.DiskPersistence;

public class TerrainServerImpl implements Remote, TerrainServer,
		TerrainPersistence {
	private static final int PORT = 6667;
	private static String ipAdress = "localhost";

	public static void main(final String[] args) {
		new TerrainServerImpl();
	}

	private final TerrainPersistence persistence = new DiskPersistence();

	public TerrainServerImpl() {
		super();
		initRMI();
	}

	@Override
	public TerrainSettings getSettings(final String directory)
			throws RemoteException {
		try {
			return persistence.getSettings(directory);
		} catch (final Exception e) {
			// we can only throw RemoteExceptions, so pass on the message at
			// least
			throw new RemoteException(e.getMessage());
		}
	}

	public TerrainData getTerrainData(final TerrainKey key,
			final String directory) throws RemoteException {
		try {
			return persistence.getTerrainData(key, directory);
		} catch (final Exception e) {
			// we can only throw RemoteExceptions, so pass on the message at
			// least
			throw new RemoteException(e.getMessage());
		}
	}

	public void initRMI() {
		final String rmiAdress = "//" + ipAdress + ":" + Integer.toString(PORT)
				+ "/" + "MapPersistence";
		try {
			LocateRegistry.createRegistry(PORT);
			UnicastRemoteObject.exportObject(this);
			Naming.rebind(rmiAdress, this);
		} catch (final java.rmi.UnknownHostException ex) {
			System.out
					.println("The IP address of a host could not be determined.");
			System.out.println(ex);
		} catch (final RemoteException ex) {
			System.out.println("Error starting service");
			System.out.println(ex);
		} catch (final MalformedURLException ex) {
			System.out
					.println("Either no legal protocol could be found in a specification "
							+ "string or the string could not be parsed. ");
			System.out.println(ex);
		}
	}

	@Override
	public void setSettings(final String directory,
			final TerrainSettings settings) throws RemoteException {
		try {
			persistence.setSettings(directory, settings);
		} catch (final Exception e) {
			// we can only throw RemoteExceptions, so pass on the message at
			// least
			throw new RemoteException(e.getMessage());
		}
	}

	public void setTerrainData(final TerrainKey key, final TerrainData mapData,
			final String directory) throws RemoteException {
		try {
			persistence.setTerrainData(key, mapData, directory);
		} catch (final Exception e) {
			// we can only throw RemoteExceptions, so pass on the message at
			// least
			throw new RemoteException(e.getMessage());
		}
	}

}
